#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
北交大教室查询系统 - 后端API服务
纯粹的RESTful API，支持前后端分离架构
"""

import os
# 导入查询模块
import sys
from contextlib import asynccontextmanager
from typing import Optional, Dict, Any

from dotenv import load_dotenv
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from query_classroom_demo.login_system import BJTSULogin
from query_classroom_demo.classroom_tool_refactored import ClassroomQueryTool, CurrentTimeInfoTool

# 加载环境变量
load_dotenv()

# 全局状态
app_state: Dict[str, Any] = {}


@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理"""
    print("Starting classroom query backend API service...")
    await initialize_app()
    print("Backend API service started successfully")
    yield
    print("Shutting down backend API service...")


# 创建FastAPI应用
app = FastAPI(
    title="北交大教室查询系统 API",
    description="北京交通大学教室查询系统后端API服务",
    version="2.0.0",
    lifespan=lifespan,
    docs_url="/docs",
    redoc_url="/redoc"
)

# CORS中间件配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "http://localhost:5173",
        "https://ff83c03a47c4.ngrok-free.app"
    ],  # 前端开发服务器端口（包括ngrok域名）
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


# Pydantic模型定义
class QueryRequest(BaseModel):
    """查询请求模型"""
    message: str = Field(..., description="用户的查询消息", min_length=1, max_length=500)
    session_id: Optional[str] = Field(None, description="会话ID（可选）")


class QueryResponse(BaseModel):
    """查询响应模型"""
    success: bool
    response: str
    session_id: Optional[str] = None
    error: Optional[str] = None
    timestamp: Optional[str] = None


class LoginRequest(BaseModel):
    """登录请求模型"""
    username: str = Field(..., description="学号")
    password: str = Field(..., description="密码")


class LoginResponse(BaseModel):
    """登录响应模型"""
    success: bool
    message: str
    session_active: bool
    user_info: Optional[Dict[str, Any]] = None


class SystemStatusResponse(BaseModel):
    """系统状态响应模型"""
    app_initialized: bool
    agent_ready: bool
    session_active: bool
    api_key_configured: bool
    server_info: Dict[str, Any]


# API路由
@app.get("/")
async def root():
    """根路径 - API信息"""
    return {
        "name": "北交大教室查询系统 API",
        "version": "2.0.0",
        "description": "教室查询系统后端API服务",
        "docs": "/docs",
        "status": "/status"
    }


@app.get("/status", response_model=SystemStatusResponse)
async def get_system_status():
    """获取系统状态"""
    return SystemStatusResponse(
        app_initialized=app_state.get("app_initialized", False),
        agent_ready=app_state.get("agent_ready", False),
        session_active=app_state.get("session_active", False),
        api_key_configured=bool(os.getenv("LONGMAO_API_KEY")),
        server_info={
            "environment": "development",
            "python_version": "3.12+",
            "fastapi_version": "0.104+"
        }
    )


@app.post("/auth/login", response_model=LoginResponse)
async def login_system(login_request: LoginRequest):
    """系统登录"""
    try:
        if not app_state.get("app_initialized"):
            raise HTTPException(status_code=503, detail="服务尚未初始化")

        login_system = app_state["login_system"]

        # 登录MIS系统
        if not login_system.login_mis_system(login_request.username, login_request.password):
            return LoginResponse(
                success=False,
                message="MIS系统登录失败，请检查用户名和密码",
                session_active=False
            )

        # 访问AA系统
        if not login_system.access_aa_system():
            return LoginResponse(
                success=False,
                message="AA系统访问失败",
                session_active=False
            )

        # 保存会话
        login_system.save_session()
        session = login_system.get_session()
        app_state["session"] = session
        app_state["session_active"] = True

        # 重新创建Agent（包含教室查询工具）
        await create_agent_with_session(session)

        return LoginResponse(
            success=True,
            message="登录成功，系统已就绪可以进行教室查询",
            session_active=True,
            user_info={
                "username": login_request.username,
                "login_time": "刚刚"
            }
        )

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"登录过程中发生错误: {str(e)}")


@app.post("/chat/query", response_model=QueryResponse)
async def query_classroom(query_request: QueryRequest):
    """教室查询接口"""
    try:
        if not app_state.get("agent_ready"):
            return QueryResponse(
                success=False,
                response="",
                error="系统尚未就绪，请等待初始化完成或检查系统状态",
                timestamp=None
            )

        agent = app_state["agent"]

        # 调用Agent处理查询
        response = agent.invoke({
            "messages": [{"role": "user", "content": query_request.message}]
        })

        # 提取响应内容
        response_text = extract_ai_response(response)

        import datetime
        timestamp = datetime.datetime.now().isoformat()

        return QueryResponse(
            success=True,
            response=response_text,
            session_id=query_request.session_id,
            timestamp=timestamp
        )

    except Exception as e:
        import datetime
        timestamp = datetime.datetime.now().isoformat()

        return QueryResponse(
            success=False,
            response="",
            error=f"查询过程中发生错误: {str(e)}",
            timestamp=timestamp
        )


@app.get("/health")
async def health_check():
    """健康检查"""
    return {
        "status": "healthy",
        "message": "教室查询系统API服务运行正常",
        "timestamp": "2025-01-01"
    }


# 辅助函数
async def initialize_app():
    """初始化应用"""
    try:
        # 检查API密钥
        zhipu_api_key = os.getenv("LONGMAO_API_KEY")
        if not zhipu_api_key:
            print("未配置智谱AI API密钥")
            app_state["app_initialized"] = True
            app_state["agent_ready"] = False
            return

        # 初始化LLM
        llm = ChatOpenAI(
            model=os.getenv("LONGMAO_MODEL", "LongCat-Flash-Chat"),
            api_key=os.getenv("LONGMAO_API_KEY"),
            base_url=os.getenv("LONGMAO_BASE_URL", "https://api.longcat.chat/openai")
        )

        # 初始化登录系统
        login_system = BJTSULogin()
        app_state["login_system"] = login_system
        app_state["llm"] = llm

        # 尝试加载已保存的会话
        session_active = False
        try:
            if login_system.load_session():
                session = login_system.get_session()
                app_state["session"] = session
                session_active = True
                print("已加载保存的会话")
                await create_agent_with_session(session)
        except Exception as e:
            print(f"会话加载失败: {e}")

        app_state["session_active"] = session_active

        # 如果没有会话，创建基础Agent
        if not session_active:
            await create_basic_agent()

        app_state["app_initialized"] = True

    except Exception as e:
        print(f"应用初始化失败: {e}")
        app_state["app_initialized"] = False
        app_state["agent_ready"] = False


async def create_basic_agent():
    """创建基础Agent（无教室查询功能）"""
    try:
        llm = app_state["llm"]
        tools = []  # 无工具，仅提示用户登录

        agent = create_agent(
            model=llm,
            tools=tools,
            system_prompt="""你是一个北京交通大学教室查询助手的欢迎助手。
你可以：
- 回答基本问题
- 解释如何使用教室查询系统
注意：当前系统未登录，无法进行教室查询。请先通过登录接口登录系统。"""
        )
        app_state["agent"] = agent
        app_state["agent_ready"] = True

    except Exception as e:
        print(f"基础Agent创建失败: {e}")


async def create_agent_with_session(session):
    """创建完整功能的Agent（包含教室查询）"""
    try:
        llm = app_state["llm"]

        # 创建工具
        classroom_tool = ClassroomQueryTool(session=session)
        time_tool = CurrentTimeInfoTool()
        tools = [classroom_tool, time_tool]

        # 创建 Agent（LangChain v1.0 API）
        agent = create_agent(
            model=llm,
            tools=tools,
            system_prompt="教室查询助手。查询明天/下周时先调get_time获取当前时间。下午=5-7节，上午=1-2节。未指定教学楼时询问。"
        )

        app_state["agent"] = agent
        app_state["agent_ready"] = True
        print("完整功能Agent创建成功")

    except Exception as e:
        print(f"完整Agent创建失败: {e}")


def extract_ai_response(response) -> str:
    """提取AI响应内容"""
    try:
        if isinstance(response, dict) and 'messages' in response:
            messages = response['messages']
            for msg in reversed(messages):
                if hasattr(msg, 'content') and msg.content.strip():
                    return msg.content.strip()
        elif isinstance(response, dict) and 'output' in response:
            return response['output'].strip()
        elif hasattr(response, 'content'):
            return response.content.strip()
        else:
            return str(response)
    except Exception:
        return "响应解析失败，但查询可能已成功执行"


if __name__ == "__main__":
    import uvicorn

    print("Starting BJTU Classroom Query Backend API...")
    print("API Documentation: http://localhost:8001/docs")
    print("Frontend URL: http://localhost:5173")

    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8001,  # 使用不同的端口避免冲突
        reload=True,
        log_level="info"
    )
